/*
 * =====================================================================================
 *
 *       Filename:  Matrix.cpp
 *
 *    Description:  The implementation of Matrix class.
 *
 *        Version:  1.0
 *        Created:  11/07/11 19:18:17
 *       Revision:  none
 *       Compiler:  g++
 *
 *         Author:  LittleQ Su (), 98703060@nccu.edu.tw
 *        Company:  National Chengchi University, The Department of Computer Science
 *
 * =====================================================================================
 */
#include "Matrix.h"
#include <iostream>

using namespace std;


// Public
Matrix::Matrix(int row, int column) {
    this -> row    = row;
    this -> column = column;

    for (int y = 0 ; y < row ; ++y ) {
        for (int x = 0; x < column ; ++x ){
            this -> content[y][x] = 0;
        }
    }
}

Matrix Matrix::operator+ (const Matrix & b) {
    Matrix result(this -> row, this -> column);

    if ( this -> isSameDiversion(b) ) {
        for (int y = 0 ; y < this -> row ; ++y ) {
            for (int x = 0 ; x < this -> column ; ++x ) {
                result.set(y, x, b.get(y, x)+this->get(y,x)); 
            }
        }
    }

    return result;

}

Matrix Matrix::operator- (const Matrix & b) {
    Matrix result(this -> row, this -> column);

    if ( this -> isSameDiversion(b) ) {
        for (int y = 0 ; y < this -> row ; ++y ) {
            for (int x = 0 ; x < this -> column ; ++x ) {
                result.set(y, x, this->get(y,x) - b.get(y, x)); 
            }
        }
    }

    return result;

}

Matrix Matrix::operator* (const Matrix & b) {
    Matrix result(this -> column, b.getColumn());
    int length = this->getRow();
    int sum;

    for (int y = 0 ; y < this -> column ; ++y ) {
        for (int x = 0 ; x < b.getColumn() ; ++x ) {
            sum = 0;
            for (int l = 0 ; l < length ; ++l ){
                sum += this -> get (y, l) * b.get(l, x);

            }
            result.set(y, x, sum); 
        }
    }

    return result;

}

void Matrix::set(int row, int column, int value) {
    this -> content[row][column] = value;
}

int Matrix::get(int row, int column) const{
    return this-> content[row][column];
}

int Matrix::getColumn() const{
    return this->column;
}

int Matrix::getRow() const{
    return this->row;
}

void Matrix::print() {
    for (int y = 0 ; y < this -> row ; ++y ){
        for ( int x = 0 ; x < this -> column ; ++x ) {
            cout << this->content[y][x] << " ";
        }
        cout << endl;
    }
}

// Private
bool Matrix::isSameDiversion(const Matrix & b) {
    if ( b.getRow() == this -> row  && b.getColumn() == this -> column ) {
        return true;
    } else {
        return false;
    }
}

